package com.tianji.remark.task;

import com.tianji.remark.config.LikedRecordConfig;
import com.tianji.remark.service.ILikedRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.core.task.TaskExecutor;
import com.xxl.job.core.handler.annotation.XxlJob;

import javax.annotation.PreDestroy;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;


/**
 * @author Covey
 */
@Component
@Slf4j
public class LikedTimesAndRecordsCheckTask {

    // 业务类型放入nacos进行管理
/*    private static final List<String> BIZ_TYPES = List.of("QA", "NOTE");
    private static final int MAX_BIZ_SIZE = 30;*/

    @Autowired
    @Lazy
    private ILikedRecordService recordService;
    @Autowired
    private LikedRecordConfig likedRecordConfig;
    @Autowired
    private TaskExecutor taskExecutor;


    // 任务状态控制标志
    private final AtomicBoolean taskEnabled = new AtomicBoolean(true);
    // 用于延迟恢复的调度器
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    private volatile ScheduledFuture<?> autoResumeFuture;

    /**
     * 主要职责：作为一个定时任务调度器，定期触发readLikedTimesAndSendMessage() 和 readLikedRecordsAndSendMessage()
     */
    // 上次执行完成后间隔20秒再执行
//    @Scheduled(fixedDelay = 20000)
    // Cron: */20 * * * * ?
    @XxlJob("checkLikedTimesAndRecords")
    public void checkLikedTimesAndRecord() {
        // 检查任务是否被暂停
        if (!taskEnabled.get()) {
            return;
        }
        try {
            List<String> bizTypes = likedRecordConfig.getBizTypes();
            Integer maxBizSize = likedRecordConfig.getMaxBizSize();
            log.debug("开始执行点赞统计任务");
            if (bizTypes == null || bizTypes.isEmpty()) {
                log.warn("业务类型配置为空，跳过本次执行");
                return;
            }
            for (String bizType : bizTypes) {
                if (bizType != null && !bizType.trim().isEmpty()) {
                    try {
                        String finalBizType = bizType.trim();
                        // 并行执行同一业务类型的两个任务
                        CompletableFuture<Void> task1 = CompletableFuture.runAsync(() ->
                                recordService.readLikedTimesAndSendMessage(finalBizType, maxBizSize), taskExecutor);
                        CompletableFuture<Void> task2 = CompletableFuture.runAsync(() ->
                                recordService.readLikedRecordsAndSendMessage(finalBizType, maxBizSize), taskExecutor);
                        // 等待两个任务都完成
                        CompletableFuture.allOf(task1, task2).join();
                        log.debug("成功处理业务类型: {}", finalBizType);
                    } catch (Exception e) {
                        log.error("处理业务类型 {} 时发生异常", bizType, e);
                    }
                }
            }
            log.debug("点赞统计任务执行完成");
            log.debug("✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨");
        } catch (Exception e) {
            log.error("点赞统计任务执行失败", e);
            log.debug("✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨");
        }
    }

    /**
     * 暂停任务指定时间，然后自动重启
     *
     * @param duration 暂停时长
     * @param unit     时间单位
     */
    public void pauseTask(long duration, TimeUnit unit) {
        if (taskEnabled.compareAndSet(true, false)) {
            log.info("点赞统计任务已暂停，将在{}后自动恢复", unit.toMinutes(duration) + "分钟");
            scheduleAutoResume(duration, unit);
        } else {
            if (autoResumeFuture == null || autoResumeFuture.isDone()) {
                log.info("任务已暂停，重新调度{}后自动恢复", unit.toMinutes(duration) + "分钟");
                scheduleAutoResume(duration, unit);
            } else {
                log.info("点赞统计任务已经是暂停状态，且已有自动恢复计划");
            }
        }
    }

    private void scheduleAutoResume(long duration, TimeUnit unit) {
        cancelAutoResume();
        autoResumeFuture = scheduler.schedule(() -> {
            if (taskEnabled.compareAndSet(false, true)) {
                log.info("点赞统计任务已自动恢复");
            }
        }, duration, unit);
    }

    public void pauseTask() {
        pauseTask(10, TimeUnit.MINUTES);
    }

    /**
     * 立即恢复任务（取消自动恢复计时器）
     */
    public void resumeTask() {
        if (taskEnabled.compareAndSet(false, true)) {
            // 取消自动恢复任务
            cancelAutoResume();
            log.info("点赞统计任务已手动恢复");
        } else {
            log.info("点赞统计任务已经是运行状态");
        }
    }

    /**
     * 取消自动恢复任务
     */
    private void cancelAutoResume() {
        if (autoResumeFuture != null && !autoResumeFuture.isDone()) {
            autoResumeFuture.cancel(false);
            autoResumeFuture = null;
        }
    }

    /**
     * 销毁方法，关闭调度器
     */
    @PreDestroy
    public void destroy() {
        cancelAutoResume();
        if (!scheduler.isShutdown()) {
            scheduler.shutdown();
            try {
                // 等待现有任务完成
                if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                    scheduler.shutdownNow(); // 强制关闭
                }
                log.info("点赞统计任务调度器已关闭");
            } catch (InterruptedException e) {
                scheduler.shutdownNow();
                Thread.currentThread().interrupt(); // 保持中断状态
                log.warn("关闭调度器时被中断");
            }
        }
    }

    /**
     * 获取任务当前状态
     *
     * @return true-运行中, false-已暂停
     */
    public boolean getTaskStatus() {
        return taskEnabled.get();
    }

    /**
     * 切换任务状态（暂停/恢复）
     *
     * @return 切换后的状态
     */
    public boolean toggleTask() {
        boolean current = taskEnabled.get();
        if (current) {
            pauseTask(); // 暂停
        } else {
            resumeTask(); // 恢复
        }
        return !current;
    }

    /**
     * 立即执行一次任务（无论是否暂停）
     */
    public void executeOnce() {
        boolean originalStatus = taskEnabled.get();
        try {
            taskEnabled.set(true);
            checkLikedTimesAndRecord();
        } finally {
            taskEnabled.set(originalStatus);
        }
    }
}